package com.bestvike.stone.spring.concurrent;

import com.bestvike.stone.spring.redis.lock.RedisDistributedLock;

import java.util.concurrent.TimeUnit;

/**
 * 可重入分布式锁
 * Created by 许崇雷 on 2018/5/31.
 */
public final class DistributedLock {
    private static final RedisDistributedLock REDIS_LOCK = new RedisDistributedLock();
    private static final long DEFAULT_WAIT_MILLIS = 0;
    private static final long DEFAULT_LEASE_MILLIS = 10 * 1000;

    /**
     * 构造函数
     */
    private DistributedLock() {
    }

    /**
     * 加锁, 不等待, 最大持有 DEFAULT_LEASE_MILLIS 毫秒
     *
     * @param name 资源名称
     * @return 成功返回锁对象, 否则抛出异常
     */
    public static LockObject lock(String name) throws LockFailedException {
        return REDIS_LOCK.acquire(name, DEFAULT_WAIT_MILLIS, DEFAULT_LEASE_MILLIS, TimeUnit.MILLISECONDS);
    }

    /**
     * 加锁, 不等待
     *
     * @param name      资源名称
     * @param leaseTime 持有时间
     * @param unit      时间单位
     * @return 成功返回锁对象, 否则抛出异常
     */
    public static LockObject lock(String name, long leaseTime, TimeUnit unit) throws LockFailedException {
        return REDIS_LOCK.acquire(name, unit.convert(DEFAULT_WAIT_MILLIS, TimeUnit.MILLISECONDS), leaseTime, unit);
    }

    /**
     * 加锁
     *
     * @param name      资源名称
     * @param waitTime  等待时间
     * @param leaseTime 持有时间
     * @param unit      时间单位
     * @return 成功返回锁对象, 否则抛出异常
     */
    public static LockObject lock(String name, long waitTime, long leaseTime, TimeUnit unit) throws LockFailedException {
        return REDIS_LOCK.acquire(name, waitTime, leaseTime, unit);
    }
}
